home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / fortran / f2c-stab.9 / f2c-stab / f2c-stabs / si-lib.stk < prev   
Encoding:
Text File  |  1996-03-31  |  13.2 KB  |  442 lines

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;; si-lib - Library for manipulating system information records (as
  3. ;;;          produced by fts-f2si).
  4. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  5. ;;;
  6. ;;; Copyright (c) 1996 Harvey J. Stein <abel@netvision.net.il>, and
  7. ;;; eventually <hjstein@netvision.net.il>
  8. ;;; All Rights Reserved.
  9. ;;; 
  10. ;;; This package is covered by the GNU GPL.  You can freely use and
  11. ;;; distribute it as long as it stays under the GNU GPL, and as long as
  12. ;;; you distribute all the corresponding source code, and as long as this
  13. ;;; message and the above copyright notice remains.
  14.  
  15. (require "formout")
  16. (require "columnout")
  17.  
  18. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  19. ;;; Top level interface
  20. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  21. (define (make-reader f-decl)
  22.   "Given a Subroutine Info table F-DECL (as generated by fts-f2si),
  23. writes (to stdout) fortran code for reading in the arguments to the
  24. subroutine defined in F-DECL." 
  25.   (header 'reader
  26.       f-decl)
  27.   (dump-reader f-decl)
  28.   (trailer))
  29.  
  30. (define (make-writer f-decl)
  31.   "Given a Subroutine Info table F-DECL (as generated by fts-f2si),
  32. writes (to stdout) fortran code for writing out the arguments to the
  33. subroutine defined in F-DECL." 
  34.   (header 'writer
  35.       f-decl)
  36.   (dump-writer f-decl)
  37.   (trailer))
  38.  
  39. (define (make-driver f-decl)
  40.   "Given a Subroutine Info table F-DECL (as generated by fts-f2si),
  41. writes (to stdout) fortran code for writing out the arguments to the
  42. subroutine defined in F-DECL." 
  43.   (header 'driver
  44.       f-decl)
  45.   (dump-driver f-decl))
  46.  
  47. (define (make-reader-and-writer si-decl)
  48. "Makes both reader and writer for subroutine described by SI-DECL.
  49. Output is to appropriate files (subname_reader.f and subname_writer.f)."
  50.   (with-output-to-file (format #f "~a_reader.f" (si-subname si-decl))
  51.                (lambda () (make-reader si-decl)))
  52.   (with-output-to-file (format #f "~a_writer.f" (si-subname si-decl))
  53.                (lambda () (make-writer si-decl)))
  54.   (with-output-to-file (format #f "~a_driver.f" (si-subname si-decl))
  55.                (lambda () (make-driver si-decl))))
  56.  
  57. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  58. ;;; Handling Subroutine Information tables.
  59. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  60.  
  61. ;;; full si record
  62. (define (si-subname f-decl)
  63.   (list-ref f-decl 0))
  64.  
  65. (define (si-filename f-decl)
  66.   (list-ref f-decl 1))
  67.  
  68. (define (si-function-type f-decl)
  69.   (list-ref f-decl 2))
  70.  
  71. (define (si-args f-decl)
  72.   (list-ref f-decl 3))
  73.  
  74. (define (si-calls f-decl)
  75.   (list-ref f-decl 4))
  76.  
  77. (define (si-locals f-decl)
  78.   (list-ref f-decl 5))
  79.  
  80. (define (si-includes f-decl)
  81.   (list-ref f-decl 6))
  82.  
  83. (define (si-externals f-decl)
  84.   (list-ref f-decl 7))
  85.  
  86. (define (si-common f-decl)
  87.   (list-ref f-decl 8))
  88.  
  89. (define (si-params f-decl)
  90.   (list-ref f-decl 9))
  91.  
  92. ;;; si argument block
  93. (define (si-arg-name arg-rec)
  94.   (list-ref arg-rec 0))
  95.  
  96. (define (si-conditioned-arg-type arg-rec)
  97.   (define screwy-char (string->regexp "\\*\\*"))
  98.   (regexp-replace screwy-char (symbol->string (si-arg-type arg-rec))
  99.            "*(*)"))
  100.   
  101.  
  102. (define (si-arg-type arg-rec)
  103.   (list-ref arg-rec 1))
  104.  
  105. (define (si-arg-dimen arg-rec)
  106.   (if (not (null? (cddr arg-rec)))
  107.       (list-ref arg-rec 2)
  108.       #f))
  109.   
  110. ;;; si include file block
  111. (define (si-incs-file-name inc-rec)
  112.   (list-ref inc-rec 0))
  113.  
  114. ;;; si common block
  115. (define (si-common-name common)
  116.   (list-ref common 0))
  117.  
  118. (define (si-common-vars common)
  119.   (list-ref common 1))
  120.  
  121. ;;; si parameters
  122. (define (si-param-name param)
  123.   (list-ref param 0))
  124.  
  125. (define (si-param-value param)
  126.   (list-ref param 1))
  127.  
  128.  
  129. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  130. ;;; Outputting pieces of the FORTRAN code for readers and writers.
  131. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  132.  
  133. ;;; Mappings from variable types to reader/writer functions.  Note
  134. ;;; that some of the mappings are bogus because certain writters don't
  135. ;;; exist and/or don't follow the correct naming conventions.
  136. (define scalar-reader-list
  137.   `((integer    . "pff_rdint")
  138.     (integer*2  . "pff_rdint")
  139.     (integer*4  . "pff_rdint")
  140.     (real       . "pff_rdreal")
  141.     (real*4     . "pff_rdreal")
  142.     (real*8     . "pff_rdreal")
  143.     (logical    . "pff_rdlog")
  144.     (logical*2  . "pff_rdlog")
  145.     (logical*4  . "pff_rdlog")))
  146.  
  147. (define array-reader-list
  148.   `((integer    . "pff_rdari4")
  149.     (integer*2  . "pff_rdari2")
  150.     (integer*4  . "pff_rdari4")
  151.     (real       . "pff_rdarr4")
  152.     (real*4     . "pff_rdarr4")
  153.     (real*8     . "pff_rdarr8")
  154.     (logical    . "pff_rdarlog4")
  155.     (logical*2  . "pff_rdarlog2")
  156.     (logical*4  . "pff_rdarlog4")))
  157.  
  158. (define scalar-writer-list
  159.   `((integer    . "pff_wri4")
  160.     (integer*2  . "pff_wri2")
  161.     (integer*4  . "pff_wri4")
  162.     (real       . "pff_wrr4")
  163.     (real*4     . "pff_wrr4")
  164.     (real*8     . "pff_wrr8")
  165.     (logical    . "pff_wrlog4")
  166.     (logical*2  . "pff_wrlog2")
  167.     (logical*4  . "pff_wrlog4")))
  168.  
  169. (define array-writer-list
  170.   `((integer    . "pff_wrari4")
  171.     (integer*2  . "pff_wrari2")
  172.     (integer*4  . "pff_wrari4")
  173.     (real       . "pff_wrarr4")
  174.     (real*4     . "pff_wrarr4")
  175.     (real*8     . "pff_wrarr8")
  176.     (logical    . "pff_wrarlog4")
  177.     (logical*2  . "pff_wrarlog2")
  178.     (logical*4  . "pff_wrarlog4")))
  179.  
  180. (define (read/write-fcn-name var-spec scalar-list array-list)
  181.   "Returns the fcn name for reading/writing VAR-SPEC.  SCALAR-LIST
  182. should be an alist matching up types to functions for scalars.
  183. ARRAY-LIST should do the same for arrays."
  184.   (let ((fnam (cond ((and (si-arg-dimen var-spec)
  185.               (= 1 (length (si-arg-dimen var-spec))))
  186.              (assoc (si-arg-type var-spec) array-list))
  187.             ((not (si-arg-dimen var-spec))
  188.              (assoc (si-arg-type var-spec) scalar-list))
  189.             (else #f))))
  190.     (if fnam (cdr fnam) "pff_unknown_guy")))
  191.  
  192. (define (write-fcn-name var-spec)
  193.   "Returns the fcn name for writing VAR-SPEC."
  194.   (read/write-fcn-name var-spec scalar-writer-list array-writer-list))
  195.  
  196. (define (read-fcn-name var-spec)
  197.   "Returns the fcn name for reading VAR-SPEC."
  198.   (read/write-fcn-name var-spec scalar-reader-list array-reader-list))
  199.  
  200. (define (write-dimen-size dim)
  201.   (define split (string->regexp "^([^:]*):(.*)$"))
  202.   (let ((split-pts (split dim)))
  203.     (if split-pts
  204.     (format #f "(~a)-(~a)+1"
  205.         (apply substring dim (list-ref split-pts 2))
  206.         (apply substring dim (list-ref split-pts 1)))
  207.     (format #f "~a" dim))))
  208.  
  209. (define (write-var var-spec)
  210.   "Writes out ftn code for writing out the value of the variable
  211. described by VAR-SPEC."
  212.   (let ((writer (write-fcn-name var-spec)))
  213.     (case (si-arg-dimen var-spec)
  214.       ;; Scalar
  215.       (#f (format-fortran-w-cont 
  216.        #t
  217.        "      CALL ~a(SI_UNIT_NUM, '~a', ~a, ' ', ' ')\n"
  218.        "     +                "
  219.        (left-10 writer)
  220.        (left-10 (si-arg-name var-spec))
  221.        (left-10 (si-arg-name var-spec))))
  222.       (else  (format-fortran-w-cont
  223.           #t
  224.           "      CALL ~a(SI_UNIT_NUM, '~a', ~a, ~a,  ' ', ' ',     5)\n"
  225.           "     +                "
  226.           (left-10 writer)
  227.           (left-10 (si-arg-name var-spec))
  228.           (left-10 (si-arg-name var-spec))
  229.           (left-10 (format #f "INT(~a)" 
  230.                    (write-dimen-size
  231.                 (car (si-arg-dimen var-spec))))) ; A wild guess...
  232.           )))))
  233.  
  234. (define (read-var var-spec)
  235.   "Writes out ftn code for reading the value of the variable
  236. described by VAR-SPEC."
  237.   (let ((reader (read-fcn-name var-spec)))
  238.     (case (si-arg-dimen var-spec)
  239.       ;; Scalar
  240.       (#f (format-fortran-w-cont
  241.        #t
  242.        "      ~a = ~a(SI_UNIT_NUM, ' ')\n"
  243.        "     +                        "
  244.        (left-10 (si-arg-name var-spec))
  245.        (left-10 reader)))
  246.       (else (format-fortran-w-cont
  247.          #t
  248.          "      CALL ~a(SI_UNIT_NUM, ' ', ~a, ~a)\n"
  249.          "     +                "
  250.          (left-10 reader)
  251.          (left-10 (si-arg-name var-spec))
  252.          (left-10 (format #f "INT(~a)" 
  253.                   (write-dimen-size
  254.                    (car (si-arg-dimen var-spec))))) ; A wild guess...
  255.          )))))
  256.  
  257. (define (write-args l)
  258.   (write-ftn-list l arg-col-out 4))
  259.  
  260. (define (header type decl)
  261.   "Dumps header for fortran subroutine named FNAM with Subroutine
  262. Information record DECL."
  263.  
  264.   (cond ((eq? type 'driver)
  265.      (format #t "C $~a$
  266.       PROGRAM ~a_~a\n\n"
  267.          "Header:"
  268.          (si-subname decl)
  269.          type))
  270.     (else
  271.      (format #t "C $~a$
  272.       SUBROUTINE ~a_~a ( SI_UNIT_NUM~a"
  273.          "Header:"
  274.          (si-subname decl)
  275.          type
  276.          (if (null? (si-args decl)) "" ","))
  277.      (write-args (map car (si-args decl)))
  278.      (format #t ")\n")))
  279.   (format #t "
  280.       IMPLICIT NONE
  281.  
  282. C Description
  283. C -----------
  284. C A ~a for subroutine ~a.  A reader for a 
  285. C subroutine is a subroutine which has the same arguments as said
  286. C subroutine (except for an additional arg SI_UNIT_NUM containing a
  287. C unit number), and reads from SI_UNIT_NUM to initialize all its
  288. C arguments.  A writer is analogous.  A driver is a program which call
  289. C the reader, call the subroutine, calls the writer, and repeats.\n"
  290.       type (si-subname decl))
  291.  
  292.   (format #t "
  293. C This file was initially generated by make-test-routines, but probably
  294. C includes lots of hand tuning by ~a, so don't just
  295. C regenerate it.
  296.  
  297. C Includes (listed before args because they might be needed)
  298. C ----------------------------------------------------------\n"
  299.           (getenv "USER"))
  300.  
  301.   (for-each (lambda (inc)
  302.           (format #t "      INCLUDE '~a'\n" (si-incs-file-name inc)))
  303.         (si-includes decl))
  304.   (format #t "
  305. C Arguments (After includes in case includes are needed).
  306. C -------------------------------------------------------
  307.       INTEGER*2       SI_UNIT_NUM\n")
  308.   (if (eq? type 'dumper)
  309.       (format #t "      INTEGER*2       SI_UNIT_OUT\n"))
  310.  
  311.   (dump-decls (si-args decl))
  312.  
  313.   (format #t "
  314. C External (not all may be needed)
  315. C --------------------------------\n")
  316.  
  317.   (if (eq? type 'reader)
  318.       (format #t "      REAL*8    pff_rdreal
  319.       INTEGER*4 pff_rdint
  320.       LOGICAL   pff_rdlog
  321.       EXTERNAL  pff_rdreal, pff_rdint, pff_rdlog\n"))
  322.  
  323.   (map (lambda (ext)
  324.      (if (assoc (car ext) (si-args decl))
  325.          (format #t "      EXTERNAL  ~a\n" (car ext))))
  326.        (si-externals decl))
  327.   (if (and (eq? type 'driver) (not (eq? '*void* (si-function-type decl))))
  328.       (format #t "      EXTERNAL  ~a\n" (si-subname decl)))
  329.   (format #t "
  330. C Code
  331. C ----\n")
  332.   (if (not (eq? type 'driver))
  333.       (format #t "
  334.       If (SI_UNIT_NUM .LT. 1) GOTO 90000 ! Allows easy turning off...
  335. \n")))
  336.  
  337. (define (dump-decls decl)
  338.   "Writes out fortran declarations for arguments listed in Subroutine
  339. Information argument declaration list DECL."
  340.  
  341.   (define (format-dimen dlist)
  342.     (define (format-dimen-aux dlist)
  343.       (cond ((null? dlist) ")\n")
  344.         ((null? (cdr dlist)) (format #t "~a)\n" (car dlist)))
  345.         (else (format #t "~a, " (car dlist))
  346.           (format-dimen-aux (cdr dlist)))))
  347.     (format #t "(")
  348.     (format-dimen-aux dlist))
  349.  
  350.   (define (dump-decl rec)
  351.     (define type-out (make-fmt-fcn "~15a"))
  352.     (format #t "      ~a ~a"
  353.         (type-out #f (si-conditioned-arg-type rec))
  354.         (si-arg-name rec))
  355.     (if (si-arg-dimen rec)
  356.     (format-dimen (si-arg-dimen rec))
  357.     (format #t "\n")))
  358.   (for-each dump-decl decl))
  359.  
  360. (define (dump-reader decl)
  361.   "Outputs fortran code for reading each argument listed in Subroutine
  362. Information record DECL."
  363.   (for-each (lambda (arg-spec)
  364.           (if (not (assoc (si-arg-name arg-spec) (si-externals decl)))
  365.           (read-var arg-spec)
  366.           (format #t "C        ~a skipped because it's external.\n" 
  367.               (si-arg-name arg-spec))))
  368.         (si-args decl)))
  369.  
  370. (define (dump-writer decl)
  371.   "Outputs fortran code for writing each argument listed in Subroutine
  372. Information record DECL."
  373.   (for-each (lambda (arg-spec)
  374.           (if (not (assoc (si-arg-name arg-spec) (si-externals decl)))
  375.           (write-var arg-spec)
  376.           (format #t "C        ~a skipped because it's external.\n" 
  377.               (si-arg-name arg-spec))))
  378.         (si-args decl)))
  379.  
  380. (define (dump-driver decl)
  381.   "Outputs call to reader, call to subroutine/function, and call to
  382. writer."
  383.   (format #t "
  384.       SI_UNIT_NUM = 5 ! Read from stdin.
  385.       SI_UNIT_OUT = 6 ! Write to stdout.
  386.  1000 CONTINUE")
  387.   (format #t "
  388.       CALL ~a_reader ( SI_UNIT_NUM~a"
  389.       (si-subname decl)
  390.       (if (null? (si-args decl)) "" ","))
  391.   (write-args (map car (si-args decl)))
  392.   (format #t ")\n")
  393.  
  394.   (format #t "
  395.       ~a ~a ("
  396.       (if (eq? (si-function-type decl) '*void*) "CALL"
  397.           (string-append (symbol->string (si-function-type decl))
  398.                  " FUNCTION"))
  399.       (si-subname decl))
  400.   (write-args (map car (si-args decl)))
  401.   (format #t ")\n")
  402.  
  403.   (format #t "
  404.       CALL ~a_writer ( SI_UNIT_OUT~a"
  405.       (si-subname decl)
  406.       (if (null? (si-args decl)) "" ","))
  407.   (write-args (map car (si-args decl)))
  408.   (format #t ")\n")
  409.  
  410.   (format #t "
  411.       GOTO 1000
  412.  
  413. 90000 continue
  414.       end\n"))
  415.  
  416. (define (trailer)
  417.   "Writes out fortran trailer code - code for closing up a subroutine call."
  418.   (format #t "
  419. 90000 continue
  420.       return
  421.       end\n"))
  422.  
  423. ;;; Miscellaneous output routines:
  424. (define (arg-col-out arg)
  425.   "Writes out symbol ARG left justified in a 15 character field."
  426.   (define arg-col-out-aux (make-fmt-fcn "~15a"))
  427.   (arg-col-out-aux #t (symbol->string arg)))
  428.  
  429. (define (left-15 arg)
  430.   "Writes out symbol ARG left justified in a 15 character field."
  431.   (define arg-col-out-aux (make-fmt-fcn "~15a"))
  432.   (arg-col-out-aux #f (if (symbol? arg) (symbol->string arg)
  433.               arg)))
  434.  
  435. (define (left-10 arg)
  436.   "Writes out symbol ARG left justified in a 10 character field."
  437.   (define arg-col-out-aux (make-fmt-fcn "~10a"))
  438.   (arg-col-out-aux #f (if (symbol? arg) (symbol->string arg)
  439.               arg)))
  440.  
  441. (provide "si-lib")
  442.